﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using CarbonExchange.Bll;

namespace CarbonExchange.Tests
{
    [TestClass]
    public class TemplateControlTypeTests : BaseTest
    {
        [TestMethod]
        public void TemplateControlType_GetById_WithIncorrectId_ReturnsNull()
        {
            TemplateControlTypeFactory factory = new TemplateControlTypeFactory(_Context);
            Assert.IsNull(factory.GetById(int.MaxValue));
        }

        [TestMethod]
        public void TemplateControlType_GetById_WithCorrectId_ReturnsNotNull()
        {
            TemplateControlTypeFactory factory = new TemplateControlTypeFactory(_Context);
            Assert.IsNotNull(factory.GetById(_TestTemplateControlTypes[2].Id));
        }

        [TestMethod]
        public void TemplateControlType_GetById_PopulatesCorrectly()
        {
            TemplateControlTypeFactory factory = new TemplateControlTypeFactory(_Context);
            var i = 2;
            var tmp = factory.GetById(_TestTemplateControlTypes[i].Id);
            Assert.IsNotNull(tmp);

            Assert.AreEqual(_TestTemplateControlTypes[i].AdminDisplayControlType, tmp.AdminDisplayControlType);
            Assert.AreEqual(_TestTemplateControlTypes[i].AdminEditControlType, tmp.AdminEditControlType);
            Assert.AreEqual(_TestTemplateControlTypes[i].CID, tmp.CID);
            Assert.AreEqual(_TestTemplateControlTypes[i].FrontEndControlType, tmp.FrontEndControlType);
            Assert.AreEqual(_TestTemplateControlTypes[i].Id, tmp.Id);
            Assert.AreEqual(_TestTemplateControlTypes[i].Name, tmp.Name);
            Assert.AreEqual(_TestTemplateControlTypes[i].Notes, tmp.Notes);
            Assert.AreEqual(_TestTemplateControlTypes[i].SiteId, tmp.SiteId);
        }

        [TestMethod]
        public void TemplateControlType_GetAllBySiteId_WithIncorrectId_ReturnsEmptyList()
        {
            TemplateControlTypeFactory factory = new TemplateControlTypeFactory(_Context);
            var tmp = factory.GetAllBySiteId(int.MaxValue);
            Assert.AreEqual(_TestTemplateControlTypes.Where(x => x.SiteId == null).Count(), tmp.Count());
        }

        [TestMethod]
        public void TemplateControlType_GetAllBySiteId_WithCorrectId_ReturnsList()
        {
            TemplateControlTypeFactory factory = new TemplateControlTypeFactory(_Context);
            var tmp = factory.GetAllBySiteId(_TestSite.Id);
            Assert.AreEqual(_TestTemplateControlTypes.Count(), tmp.Count());
        }

        [TestMethod]
        public void TemplateControlType_GetAllBySiteId_PopulatesCorrectly()
        {
            TemplateControlTypeFactory factory = new TemplateControlTypeFactory(_Context);
            var tmpList = factory.GetAllBySiteId(_TestSite.Id);
            Assert.AreEqual(_TestTemplateControlTypes.Count(), tmpList.Count());
            int i = 0;
            foreach (var tmp in tmpList)
            {
                Assert.AreEqual(_TestTemplateControlTypes[i].AdminDisplayControlType, tmp.AdminDisplayControlType);
                Assert.AreEqual(_TestTemplateControlTypes[i].AdminEditControlType, tmp.AdminEditControlType);
                Assert.AreEqual(_TestTemplateControlTypes[i].CID, tmp.CID);
                Assert.AreEqual(_TestTemplateControlTypes[i].FrontEndControlType, tmp.FrontEndControlType);
                Assert.AreEqual(_TestTemplateControlTypes[i].Id, tmp.Id);
                Assert.AreEqual(_TestTemplateControlTypes[i].Name, tmp.Name);
                Assert.AreEqual(_TestTemplateControlTypes[i].Notes, tmp.Notes);
                Assert.AreEqual(_TestTemplateControlTypes[i].SiteId, tmp.SiteId);
                i++;
            }
        }

        [TestMethod]
        public void TemplateControlType_DeleteOne()
        {
            TemplateControlTypeFactory factory = new TemplateControlTypeFactory(_Context);
            var tmp = factory.GetById(_TestTemplateControlTypes[0].Id);
            Assert.IsNotNull(tmp);
            factory.Delete(tmp);
            Assert.IsNull(factory.GetById(_TestTemplateControlTypes[0].Id));
            Assert.AreEqual(_TestTemplateControlTypes.Count - 1, factory.GetAllBySiteId(_TestSite.Id).Count());
        }

        [TestMethod]
        public void TemplateControlType_DeleteMany()
        {
            TemplateControlTypeFactory factory = new TemplateControlTypeFactory(_Context);
            var tmp = factory.GetAllBySiteId(_TestSite.Id);
            Assert.IsTrue(tmp.Count() > 0);
            factory.Delete(tmp);
            Assert.IsNull(factory.GetById(_TestTemplateControlTypes[0].Id));
            Assert.AreEqual(0, factory.GetAllBySiteId(_TestSite.Id).Count());
        }

        [TestMethod]
        public void TemplateControlType_UpdateOne()
        {
            TemplateControlTypeFactory factory = new TemplateControlTypeFactory(_Context);
            var tmp = factory.GetById(_TestTemplateControlTypes[0].Id);
            Assert.IsNotNull(tmp);

            tmp.AdminDisplayControlType = "Acms.AdminDisplayControlTypeUpdate";
            tmp.AdminEditControlType = "Acms.AdminEditControlTypeUpdate";
            tmp.FrontEndControlType = "Acms.FrontEndControlTypeUpdate";
            tmp.Name = "Update Name";
            tmp.Notes = "Update Notes";

            var cid = tmp.CID;

            factory.Save(tmp);

            Assert.AreEqual(_TestTemplateControlTypes[0].Id, tmp.Id);
            Assert.AreEqual("Acms.AdminDisplayControlTypeUpdate", tmp.AdminDisplayControlType);
            Assert.AreEqual("Acms.AdminEditControlTypeUpdate", tmp.AdminEditControlType);
            Assert.AreEqual("Acms.FrontEndControlTypeUpdate", tmp.FrontEndControlType);
            Assert.AreEqual("Update Name", tmp.Name);
            Assert.AreEqual("Update Notes", tmp.Notes);
            Assert.AreNotEqual(cid, tmp.CID);

            var tmp2 = factory.GetById(tmp.Id);

            Assert.AreEqual(tmp2.Id, tmp.Id);
            Assert.AreEqual(tmp2.AdminDisplayControlType, tmp.AdminDisplayControlType);
            Assert.AreEqual(tmp2.AdminEditControlType, tmp.AdminEditControlType);
            Assert.AreEqual(tmp2.FrontEndControlType, tmp.FrontEndControlType);
            Assert.AreEqual(tmp2.Name, tmp.Name);
            Assert.AreEqual(tmp2.Notes, tmp.Notes);
            Assert.AreEqual(tmp2.CID, tmp.CID);
        }

        [TestMethod]
        public void TemplateControlType_UpdateMany()
        {
            TemplateControlTypeFactory factory = new TemplateControlTypeFactory(_Context);
            var tmpList = factory.GetAllBySiteId(_TestSite.Id).ToList();
            
            Assert.IsNotNull(tmpList);

            object[] cids = new object[tmpList.Count()];
            int i = 0;
            foreach (var tmp in tmpList)
            {
                tmp.AdminDisplayControlType = "Acms.AdminDisplayControlTypeUpdate{0}".Format(i);
                tmp.AdminEditControlType = "Acms.AdminEditControlTypeUpdate{0}".Format(i);
                tmp.FrontEndControlType = "Acms.FrontEndControlTypeUpdate{0}".Format(i);
                tmp.Name = "Update Name {0}".Format(i);
                tmp.Notes = "Update Notes {0}".Format(i);
                cids[i] = tmp.CID;
                i++;
            }

            factory.Save(tmpList);

            i = 0;
            foreach (var tmp in tmpList)
            {
                Assert.AreEqual(_TestTemplateControlTypes[i].Id, tmp.Id);
                Assert.AreEqual("Acms.AdminDisplayControlTypeUpdate{0}".Format(i), tmp.AdminDisplayControlType);
                Assert.AreEqual("Acms.AdminEditControlTypeUpdate{0}".Format(i), tmp.AdminEditControlType);
                Assert.AreEqual("Acms.FrontEndControlTypeUpdate{0}".Format(i), tmp.FrontEndControlType);
                Assert.AreEqual("Update Name {0}".Format(i), tmp.Name);
                Assert.AreEqual("Update Notes {0}".Format(i), tmp.Notes);
                Assert.AreNotEqual(cids[i], tmp.CID);
                i++;
            }

            var tmpList2 = factory.GetAllBySiteId(_TestSite.Id).ToArray();

            i = 0;

            foreach(var tmp in tmpList)
            {
                var tmp2 = tmpList2[i];

                Assert.AreEqual(tmp2.Id, tmp.Id);
                Assert.AreEqual(tmp2.AdminDisplayControlType, tmp.AdminDisplayControlType);
                Assert.AreEqual(tmp2.AdminEditControlType, tmp.AdminEditControlType);
                Assert.AreEqual(tmp2.FrontEndControlType, tmp.FrontEndControlType);
                Assert.AreEqual(tmp2.Name, tmp.Name);
                Assert.AreEqual(tmp2.Notes, tmp.Notes);
                Assert.AreEqual(tmp2.CID, tmp.CID);

                i++;
            }
        }

        [TestMethod]
        public void TemplateControlType_InsertOne()
        {
            TemplateControlTypeFactory factory = new TemplateControlTypeFactory(_Context);
            var tmp = new TemplateControlType(_AlternateSite.Id);

            tmp.AdminDisplayControlType = "AdminDisplayControlTypeInsertTest";
            tmp.AdminEditControlType = "AdminEditControlTypeInsertTest";
            tmp.FrontEndControlType = "FrontEndControlTypeInsertTest";
            tmp.Name = "Insert Name";
            tmp.Notes = "Insert Notes";

            factory.Save(tmp);

            Assert.AreEqual(_Context.TemplateControlTypes.OrderByDescending(x => x.Id).First().Id, tmp.Id);
            Assert.AreEqual("AdminDisplayControlTypeInsertTest", tmp.AdminDisplayControlType);
            Assert.AreEqual("AdminEditControlTypeInsertTest", tmp.AdminEditControlType);
            Assert.AreEqual("FrontEndControlTypeInsertTest", tmp.FrontEndControlType);
            Assert.AreEqual("Insert Name", tmp.Name);
            Assert.AreEqual("Insert Notes", tmp.Notes);
            Assert.AreEqual(_Context.TemplateControlTypes.OrderByDescending(x => x.Id).First().CID, tmp.CID);
            
            var tmp2 = factory.GetById(tmp.Id);
            Assert.AreEqual(tmp2.Id, tmp.Id);
            Assert.AreEqual(tmp2.AdminDisplayControlType, tmp.AdminDisplayControlType);
            Assert.AreEqual(tmp2.AdminEditControlType, tmp.AdminEditControlType);
            Assert.AreEqual(tmp2.FrontEndControlType, tmp.FrontEndControlType);
            Assert.AreEqual(tmp2.Name, tmp.Name);
            Assert.AreEqual(tmp2.Notes, tmp.Notes);
            Assert.AreEqual(tmp2.CID, tmp.CID);

            Assert.AreEqual(_TestTemplateControlTypes.Where(x => x.SiteId == null).Count() + 1, factory.GetAllBySiteId(_AlternateSite.Id).Count());
        }

        [TestMethod]
        public void TemplateControlType_InsertMany()
        {
            TemplateControlTypeFactory factory = new TemplateControlTypeFactory(_Context);
            int noToGen = 3;
            List<TemplateControlType> tmpList = new List<TemplateControlType>();
            for(int i = 0; i < noToGen; i++)
            {

                var tmp = new TemplateControlType(_AlternateSite.Id);

                tmp.AdminDisplayControlType = "AdminDisplayControlTypeInsertTest{0}".Format(i);
                tmp.AdminEditControlType = "AdminEditControlTypeInsertTest{0}".Format(i);
                tmp.FrontEndControlType = "FrontEndControlTypeInsertTest{0}".Format(i);
                tmp.Name = "Insert Name {0}".Format(i);
                tmp.Notes = "Insert Notes {0}".Format(i);

                tmpList.Add(tmp);
            }

            factory.Save(tmpList);

            for (int i = 0; i < noToGen; i++)
            {
                var tmp = tmpList[i];
                Assert.AreEqual(_Context.TemplateControlTypes.OrderByDescending(x => x.Id).Skip(noToGen - i - 1).First().Id, tmp.Id);
                Assert.AreEqual("AdminDisplayControlTypeInsertTest{0}".Format(i), tmp.AdminDisplayControlType);
                Assert.AreEqual("AdminEditControlTypeInsertTest{0}".Format(i), tmp.AdminEditControlType);
                Assert.AreEqual("FrontEndControlTypeInsertTest{0}".Format(i), tmp.FrontEndControlType);
                Assert.AreEqual("Insert Name {0}".Format(i), tmp.Name);
                Assert.AreEqual("Insert Notes {0}".Format(i), tmp.Notes);
                Assert.AreEqual(_Context.TemplateControlTypes.OrderByDescending(x => x.Id).Skip(noToGen - i - 1).First().CID, tmp.CID);
            }

            var tmpList2 = factory.GetAllBySiteId(_AlternateSite.Id).ToList();
            for (int i = 0; i < noToGen; i++)
            {
                var tmp = tmpList[i];
                var tmp2 = tmpList2.Find(x => x.Id == tmp.Id);
                Assert.AreEqual(tmp2.Id, tmp.Id);
                Assert.AreEqual(tmp2.AdminDisplayControlType, tmp.AdminDisplayControlType);
                Assert.AreEqual(tmp2.AdminEditControlType, tmp.AdminEditControlType);
                Assert.AreEqual(tmp2.FrontEndControlType, tmp.FrontEndControlType);
                Assert.AreEqual(tmp2.Name, tmp.Name);
                Assert.AreEqual(tmp2.Notes, tmp.Notes);
                Assert.AreEqual(tmp2.CID, tmp.CID);
            }
        }

        [TestMethod]
        [ExpectedException(typeof(Bll.Exceptions.ValidationException))]
        public void TemplateControlType_NoAdminDisplayControlType_ThrowsException()
        {
            TemplateControlTypeFactory factory = new TemplateControlTypeFactory(_Context);
            var tmp = new TemplateControlType(_AlternateSite.Id);

            tmp.AdminEditControlType = "AdminEditControlTypeInsertTest";
            tmp.FrontEndControlType = "FrontEndControlTypeInsertTest";
            tmp.Name = "Insert Name";
            tmp.Notes = "Insert Notes";

            factory.Save(tmp);
        }

        [TestMethod]
        [ExpectedException(typeof(Bll.Exceptions.ValidationException))]
        public void TemplateControlType_NoAdminEditControlType_ThrowsException()
        {
            TemplateControlTypeFactory factory = new TemplateControlTypeFactory(_Context);
            var tmp = new TemplateControlType(_AlternateSite.Id);

            tmp.AdminEditControlType = "AdminEditControlTypeInsertTest";
            tmp.FrontEndControlType = "FrontEndControlTypeInsertTest";
            tmp.Name = "Insert Name";
            tmp.Notes = "Insert Notes";

            factory.Save(tmp);
        }

        [TestMethod]
        [ExpectedException(typeof(Bll.Exceptions.ValidationException))]
        public void TemplateControlType_NoFrontEndControlType_ThrowsException()
        {
            TemplateControlTypeFactory factory = new TemplateControlTypeFactory(_Context);
            var tmp = new TemplateControlType(_AlternateSite.Id);

            tmp.AdminDisplayControlType = "AdminDisplayControlTypeInsertTest";
            tmp.AdminEditControlType = "AdminEditControlTypeInsertTest";
            tmp.Name = "Insert Name";
            tmp.Notes = "Insert Notes";

            factory.Save(tmp);
        }

        [TestMethod]
        [ExpectedException(typeof(Bll.Exceptions.ValidationException))]
        public void TemplateControlType_NoName_ThrowsException()
        {
            TemplateControlTypeFactory factory = new TemplateControlTypeFactory(_Context);
            var tmp = new TemplateControlType(_AlternateSite.Id);

            tmp.AdminDisplayControlType = "AdminDisplayControlTypeInsertTest";
            tmp.AdminEditControlType = "AdminEditControlTypeInsertTest";
            tmp.FrontEndControlType = "FrontEndControlTypeInsertTest";
            tmp.Notes = "Insert Notes";

            factory.Save(tmp);
        }

    }
}
